﻿using AutoMapper;
using System.Reflection;

namespace DDD.Application
{
    public abstract class AutoMapperProfile : Profile
    {
        public AutoMapperProfile()
        {
            //Console.WriteLine("Assembly.GetCallingAssembly().FullName:{0}", Assembly.GetCallingAssembly().FullName);
            //Console.WriteLine("Assembly.GetEntryAssembly().FullName:{0}", Assembly.GetEntryAssembly()?.FullName);
            //Console.WriteLine("Assembly.GetExecutingAssembly().FullName:{0}", Assembly.GetExecutingAssembly().FullName);

            var appAssembly = Assembly.GetCallingAssembly();
            var appTypes = appAssembly.GetExportedTypes();

            foreach (Type item in appTypes)
            {
                if (item is null)
                {
                    continue;
                }

                var fromAttrs = item.GetCustomAttributes(typeof(AutoMapperFromAttribute));
                var toAttrs = item.GetCustomAttributes(typeof(AutoMapperToAttribute));

                foreach (AutoMapperFromAttribute fromAttr in fromAttrs)
                {
                    var mappingExpression = this.CreateMap(fromAttr.Type, item);
                    foreach (var p in item.GetProperties())
                    {
                        if (p.GetCustomAttributes().Any(e => e.GetType().Name == "NotMappedAttribute"))
                        {
                            mappingExpression.ForMember(p.Name, opt => opt.Ignore());
                        }
                    }
                }

                foreach (AutoMapperToAttribute toAttr in toAttrs)
                {
                    var mappingExpression = this.CreateMap(item, toAttr.Type);
                    foreach (var p in item.GetProperties())
                    {
                        if (p.GetCustomAttributes().Any(e => e.GetType().Name == "NotMappedAttribute"))
                        {
                            mappingExpression.ForMember(p.Name, opt => opt.Ignore());
                        }
                    }
                }

                //var fromAttr = item.GetCustomAttribute(typeof(AutoMapperFromAttribute)) as AutoMapperFromAttribute;
                //var toAttr = item.GetCustomAttribute(typeof(AutoMapperToAttribute)) as AutoMapperToAttribute;
                //if (fromAttr != null)
                //{
                //    var domain = fromAttr.Type;
                //    var mappingExpression = this.CreateMap(domain, item);
                //    foreach (var p in item.GetProperties())
                //    {
                //        if (p.GetCustomAttributes().Any(e => e.GetType().Name == "NotMappedAttribute"))
                //        {
                //            mappingExpression.ForMember(p.Name, opt => opt.Ignore());
                //        }
                //    }
                //}
                //if (toAttr != null)
                //{
                //    var domain = toAttr.Type;
                //    var mappingExpression = this.CreateMap(item, domain);
                //    foreach (var p in item.GetProperties())
                //    {
                //        if (p.GetCustomAttributes().Any(e => e.GetType().Name == "NotMappedAttribute"))
                //        {
                //            mappingExpression.ForMember(p.Name, opt => opt.Ignore());
                //        }
                //    }
                //}
            }
        }

    }

}
